// 全局方法与平台信息（注册到 app.config.globalProperties）
// 说明：在模板中可直接使用 $platform，例如：<view v-if="$platform.isH5">H5</view>
// 在 <script setup> 中可通过 getCurrentInstance().proxy?.$platform 访问，无需 import 本文件。

import type { App, Plugin } from "vue";
export function debounce<T extends (...args: any[]) => void>(
  fn: T,
  wait = 300,
  options: { leading?: boolean; trailing?: boolean } = {}
) {
  let timer: ReturnType<typeof setTimeout> | null = null;
  let lastCallArgs: Parameters<T> | null = null;
  let invoked = false;
  const { leading = false, trailing = true } = options;

  const invoke = (args: Parameters<T>) => {
    timer = null;
    invoked = true;
    fn(...args);
  };

  const debounced = function (
    this: ThisParameterType<T>,
    ...args: Parameters<T>
  ) {
    lastCallArgs = args;
    const shouldCallLeading = leading && !timer && !invoked;

    if (timer) clearTimeout(timer);

    if (shouldCallLeading) {
      invoke(args);
    } else if (trailing) {
      timer = setTimeout(() => {
        if (!leading || invoked) invoke(lastCallArgs as Parameters<T>);
        invoked = false;
      }, wait);
    }
  };

  debounced.cancel = () => {
    if (timer) clearTimeout(timer);
    timer = null;
    invoked = false;
    lastCallArgs = null;
  };

  return debounced;
}


export interface PlatformInfo {
  // 编译平台标记
  isApp: boolean;
  isH5: boolean;
  isMpWeixin: boolean;
  isMpAlipay: boolean;
  // 操作系统标记
  isAndroid: boolean;
  isIOS: boolean;
  // 平台标识字符串（h5 / app-plus / mp-weixin / mp-alipay ...）
  platform: string;
  // 操作系统（尽量兼容：优先 osName，否则 platform）
  osName: string;
  // 系统信息（完整）
  systemInfo: UniApp.GetSystemInfoResult;
  debounce: any;

}

function detectPlatform(): PlatformInfo {
  // 编译期条件编译，生成稳定标记
  let platform = "unknown";
  let isApp = false;
  let isH5 = false;
  let isMpWeixin = false;
  let isMpAlipay = false;

  // #ifdef APP-PLUS
  platform = "app-plus";
  isApp = true;
  // #endif
  // #ifdef H5
  platform = "h5";
  isH5 = true;
  // #endif
  // #ifdef MP-WEIXIN
  platform = "mp-weixin";
  isMpWeixin = true;
  // #endif
  // #ifdef MP-ALIPAY
  platform = "mp-alipay";
  isMpAlipay = true;
  // #endif

  const sys = uni.getSystemInfoSync();
  const rawOS =
    (sys as any).osName ||
    (sys as any).os ||
    sys.platform ||
    (sys as any).system ||
    "";
  const ua =
    typeof navigator !== "undefined" ? navigator.userAgent.toLowerCase() : "";
  const lowerOS = String(rawOS).toLowerCase();
  const isAndroid = /android/.test(lowerOS) || /android/.test(ua);
  const isIOS =
    /(ios|iphone|ipad|ipod)/.test(lowerOS) || /(iphone|ipad|ipod)/.test(ua);
  const osName = lowerOS || (isAndroid ? "android" : isIOS ? "ios" : "unknown");

  return {
    isApp,
    isH5,
    isMpWeixin,
    isMpAlipay,
    isAndroid,
    isIOS,
    platform,
    osName,
    debounce,
    systemInfo: sys,
  };
}

const GlobalPlugin: Plugin = {
  install(app: App) {
    const p = detectPlatform();
    Object.entries(p).forEach(([key, val]) => {
      (globalThis as any)[`${key}`] = val;
    });
    (globalThis as any)[`$platform`] = p;
  },
};

export default GlobalPlugin;
